<?php


namespace App\Http\Services\Admin\AdminOplogConvert;


abstract class CommonConvert
{
    protected $fieldMap;                    //字段映射
    protected $valueMap;                    //值映射
    protected $nowFieldType = 'json';       //数据当前格式
    protected $convertField = [             //默认需要转换字段
        'old_data',
        'new_data',
    ];
    protected $resultData = [];             //返回
    protected $requestData = [];            //注入
    protected $convertData = [];            //待处理中数据
    protected $typeMethod = [               //已支持的解码方式
        'json' => [
            'jsonDecode',
        ],
        'array' => [],
    ];


    public function __construct(array $requestData)
    {
        $this->requestData = $requestData;
    }

    /**
     * @return array fieldMap
     */
    abstract public function fieldMap();

    /**
     * @return array valueMap
     */
    abstract public function valueMap();


    protected function injectConvertData()
    {
        if (empty($this->convertField)) throw new \RuntimeException('NOT FOUND convert_field');

        array_walk($this->convertField, function ($v) {
            $this->convertData[$v] = $this->requestData[$v];
        });

        $method = $this->typeMethod[$this->nowFieldType][0];
        if (!empty($method))
            $this->convertData = array_map(function ($v) use ($method) {
                return $this->{$method}($v);
            }, $this->convertData);

        return $this;

    }

    protected function exchange($key, $valueData)
    {
        $this->fieldMap = $this->fieldMap();
        $this->valueMap = $this->valueMap();

        $newResult = [];
        foreach ($valueData as $k => $v) {
            if (array_key_exists($k, $this->valueMap)) $v = $this->valueMap[$k][$v];
            $newResult[$this->fieldMap[$k]] = $v;
        }
        $this->resultData[$key] = $newResult;
    }

    protected function convertData()
    {
        if (empty($this->convertData)) return [];
        foreach ($this->convertData as $k => $v) {
            $this->exchange($k, $v);
        }
        return $this;
    }

    public function getData()
    {
        $this->injectConvertData()->convertData();
        return $this->resultData + $this->requestData; #原转换数据使用新数据覆盖
    }

    //***********
    //   METHOD
    //***********

    protected function jsonDecode(string $data)
    {
        return json_decode($data, true);
    }

}
